package com.cskaoyan.javase.homework.senior._05thread;

/**
 * @description:
 * @author: 景天
 * @date: 2022/2/11 11:30
 **/

import org.junit.Test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;


/*
要求: 从0-9这10个数中

- 生成一个长度是3的随机数字，把这个字符串当作密码
- 创建一个破解线程，使用穷举法，匹配这个密码,直到匹配到正确的
- 创建一个日志线程，将用过的字符串写入文件，这个日志线程设计为守护线程

提示： 破解线程把穷举法生成的可能密码放在一个容器中，这个容器存储匹配过程中用到的密码。
容器中存储的最后一个字符串就是正确的密码
日志线程把这个容器中的密码并打印出来。(因为没有学集合,先用数组)
注意:  守护线程的特征,jvm中只有守护线程 jvm退出

可能出现的情况:
- 穷举完了 还没写入 程序就已经终止了
- 穷举完了 写了一半 程序就终止了
 */
public class Work3 {
    public static String password;
    public static String[] passwords = new String[(int) Math.pow(10, 3)];

    public static void main(String[] args) throws InterruptedException {
        // 随机生成密码
        password = createRandomPassword(3);
        System.out.println("password: " + password);
        // 启动穷举线程
        Thread matchThread = new Thread(
                // lambda表达式 也可以用匿名内部类
                () -> matchPassword(password)
        );
        matchThread.start();
        // 让穷举线程插队完成密码破解
        matchThread.join();
        // 启动日志线程
        System.out.println(Arrays.toString(passwords));
        Thread logThread = new Thread(
                () -> {
                    try (FileOutputStream out = new FileOutputStream("password.txt")) {
                        for (int i = 0; i < passwords.length; i++) {
                            if (i < findPwdIndex()) {
                                out.write(("已经验证且不是密码:" + passwords[i]).getBytes());
                                out.write("\r\n".getBytes());
                            }
                            if (i == findPwdIndex()) {
                                out.write((("随机生成的密码是:" + (Integer.parseInt(passwords[i]))).getBytes()));
                                break;
                            }
                            // if (passwords[i] != null) {
                            //     out.write(("已经验证且不是密码:" + passwords[i]).getBytes());
                            //     out.write("\r\n".getBytes());
                            // } else {
                            //     out.write((("随机生成的密码是:" + (Integer.parseInt(passwords[i - 1]) + 1)).getBytes()));
                            //     break;
                            // }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
        );
        logThread.setDaemon(true);
        logThread.start();
        // 在这睡眠是为了让main线程不死,不死的话那么jvm中就还有用户线程,虚拟机就不会退出
        // 等到日志线程执行完了再死
        Thread.sleep(5000);
    }

    private static int findPwdIndex() {
        for (int i = 0; i < passwords.length; i++) {
            if (password.equals(passwords[i])) {
                return i;
            }
        }
        return -1;
    }

    private static void matchPassword(String password) {
        // 所有的可能性就是000 - 999
        // 列一个 不是就放入到数组中
        for (int i = 0; i < passwords.length; i++) {
            /*
                这里进行了一次格式化字符串,表示将不足三位数的int值
                前面补0
                比如对于i=10,possiblePassword就=010
             */
            String possiblePassword = String.format("%03d", i);
            System.out.println(possiblePassword);
            if (password.equals(possiblePassword)) {
                // 最后一个是匹配到的密码
                passwords[i] = possiblePassword;
                break;
            } else {
                passwords[i] = possiblePassword;
            }
        }

    }

    /**
     * 随机生成一共密码
     * @param len 密码长度
     * @return password
     */
    private static String createRandomPassword(int len) {
        char[] chars = new char[len];
        String s = "0123456789";
        for (int i = 0; i < chars.length; i++) {
            chars[i] = s.charAt((int) (Math.random() * s.length()));
        }
        return new String(chars);
    }

    @Test
    public void test() {
        System.out.println(createRandomPassword(3));
    }
}

